package com.zjj.disk.controller;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zjj.disk.config.ImportValidationException;
import com.zjj.disk.controller.result.Result;
import com.zjj.disk.pojo.*;
import com.zjj.disk.pojo.Dictionary;
import com.zjj.disk.service.BookKeepingService;
import com.zjj.disk.service.DictionaryService;
import net.sf.cglib.core.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/bookKeeping")
public class BookKeepingController {

    @Autowired
    private BookKeepingService bookKeepingService;

    @Autowired
    private DictionaryService dictionaryService;

    @GetMapping("/getList")
    public IPage<BookKeepingDTO> getBookKeepingsByConditions(@ModelAttribute BookKeepingDTO queryDto,
                                                             @RequestParam(defaultValue = "1") int currentPage,
                                                             @RequestParam(defaultValue = "10") int pageSize) {
        return bookKeepingService.getBookKeepingByConditions(queryDto, currentPage, pageSize);
    }

    @GetMapping("/detailedBooks")
    public Result getDetailedBooks() {
        return bookKeepingService.detailedBooks();
    }

    /**
     * 新增记账记录
     *
     * @param bookKeepingDTO 记账记录 DTO
     * @return 是否成功
     */
    @PostMapping("/add")
    public boolean addBookKeeping(@RequestBody BookKeepingDTO bookKeepingDTO) {
        return bookKeepingService.addBookKeeping(bookKeepingDTO);
    }

    /**
     * 获取当前月的总收入、总支出及各项目的盈亏情况
     *
     * @param userName 用户名称
     * @return 包含总收入、总支出及各项目盈亏情况的Map
     */
    @GetMapping("/currentMonthSummary")
    public Map<String, Object> getCurrentMonthSummary(@RequestParam String userName, @RequestParam String yearMonth) {
        return bookKeepingService.getCurrentMonthSummary(userName, yearMonth);
    }

    @GetMapping("/download")
    public void downloadExcel(HttpServletResponse response) throws IOException {
        // 查询所有账目记录
        QueryWrapper<BookKeeping> queryWrapper = new QueryWrapper<>();
        List<BookKeeping> bookKeepings = bookKeepingService.list(queryWrapper);

        // 将 BookKeeping 对象转换为 BookKeepingExport 对象
        List<BookKeepingExport> exportList = convertToExportList(bookKeepings);

        // 生成带有时间戳的文件名
        String fileName = URLEncoder.encode(System.currentTimeMillis() + "_账目记录", "UTF-8").replaceAll("\\+", "%20");

        // 设置响应头
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");

        // 使用 EasyExcel 写入 Excel 文件
        EasyExcel.write(response.getOutputStream(), BookKeepingExport.class).sheet("账目记录").doWrite(exportList);
    }


    private List<BookKeepingExport> convertToExportList(List<BookKeeping> bk) {
        List<Dictionary> byParentCode = dictionaryService.getByParentCode("user_info");
        Map<String, String> codeNameMap = createCodeNameMap(byParentCode);

        return bk.stream()
                .map(bookKeeping -> convertToExport(bookKeeping, codeNameMap))
                .collect(Collectors.toList());
    }

    private Map<String, String> createCodeNameMap(List<Dictionary> byParentCode) {
        if (byParentCode == null || byParentCode.isEmpty()) {
            return new HashMap<>();
        }
        return byParentCode.stream()
                .collect(Collectors.toMap(Dictionary::getCode, Dictionary::getName));
    }

    private BookKeepingExport convertToExport(BookKeeping bookKeeping, Map<String, String> codeNameMap) {
        BookKeepingExport export = new BookKeepingExport();
        export.setProject(bookKeeping.getProject());
        export.setType(TransactionType.getNameByCode(bookKeeping.getType())); // 枚举类型转换
        export.setFormattedTime(bookKeeping.getFormattedTime());
        export.setAmount(bookKeeping.getAmount());
        export.setUserName(getUserName(bookKeeping, codeNameMap));
        export.setRemark(bookKeeping.getRemark());
        return export;
    }

    private String getUserName(BookKeeping bookKeeping, Map<String, String> codeNameMap) {
        return codeNameMap.getOrDefault(bookKeeping.getUserName(), bookKeeping.getUserName());
    }

    @PostMapping("/import")
    public ResponseEntity<String> importFromExcel(@RequestParam("file") MultipartFile file) {
        try {
            List<BookKeeping> bookKeepings = bookKeepingService.importFromExcel(file);
            return ResponseEntity.ok("文件导入成功");
        } catch (ImportValidationException e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("文件导入失败: " + e.getMessage());
        } catch (RuntimeException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("文件导入失败: " + e.getMessage());
        }
    }

    @PostMapping("/delete")
    public String deleteByIds(@RequestBody List<Integer> ids) {
        int result = bookKeepingService.deleteByIds(ids);
        if (result > 0) {
            return "删除成功，共删除 " + result + " 条记录";
        } else {
            return "删除失败，没有找到对应的记录";
        }
    }

    @PostMapping
    public boolean addBookKeeping(@RequestBody BookKeeping bookKeeping) {
        return bookKeepingService.save(bookKeeping);
    }

    @DeleteMapping("/{id}")
    public boolean deleteBookKeeping(@PathVariable Integer id) {
        return bookKeepingService.removeById(id);
    }

    @PostMapping("/updateBook")
    public boolean updateBookKeeping(@RequestBody BookKeeping bookKeeping) {
        return bookKeepingService.updateById(bookKeeping);
    }

    @GetMapping("getAllBookKeeping")
    public List<BookKeeping> getAllBookKeepings() {
        return bookKeepingService.list();
    }

    @GetMapping("/{id}")
    public BookKeeping getBookKeepingById(@PathVariable Integer id) {
        return bookKeepingService.getById(id);
    }
}
